package com.yuandian.management.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuandian.api.management.entity.ConfProbeDataFilter;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.management.mapper.ConfProbeDataFilterMapper;
import com.yuandian.management.service.ConfProbeDataFilterService;
import com.yuandian.management.socket.client.DefaultSocketClient;
import com.yuandian.management.socket.client.SocketClient;
import lombok.extern.slf4j.Slf4j;
import org.ini4j.Ini;
import org.ini4j.Wini;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.*;


/**
 * 探针数据过滤表-Service实现
 * @author zfsn
 * @date 2023-4-10
 */
@Slf4j
@Service
public class ConfProbeDataFilterServiceImpl extends ServiceImpl<ConfProbeDataFilterMapper, ConfProbeDataFilter>
		implements ConfProbeDataFilterService {

	@Autowired
	ConfProbeDataFilterMapper confProbeDataFilterMapper;

	@Resource
	private NacosConfigManager nacosConfigManager;


	/**
	 * 分页查询
	 *
	 * @param confProbeDataFilter 筛选条件
	 * @return 通用返回对象
	 */
	@Override
	public Page<ConfProbeDataFilter> listPage(ConfProbeDataFilter confProbeDataFilter) {
		return confProbeDataFilterMapper.listPage(new Page<>(confProbeDataFilter.getPageNum(), confProbeDataFilter.getPageSize()), confProbeDataFilter);
	}

	/**
	 * 向探针同步过滤信息
	 *
	 * @param confProbeDataFilter 参数
	 * @return Result
	 */
	@Override
	public R startSynFilterData(ConfProbeDataFilter confProbeDataFilter) {
		Map<String, Object> resultData = new HashMap<>(6);
		//要发送的json数据
		String dataJson = null;
		//统计成功的个数
		int count = 0;
		String[] proId = confProbeDataFilter.getIds().split(",");
		//统计失败的id
		List<String> resultlistip = new ArrayList<>(Arrays.asList(proId));
		//统计成功的id
		List<String> successid = new ArrayList<>();
		//统计正在运行的id
		List<String> runid = new ArrayList<>();
		for (String idd : proId) {
			try {
				Integer dataId = Integer.parseInt(idd);
				ConfProbeDataFilter queryProbeDataFilter = super.getById(dataId);
				// 调用字符串拼接
				String sendDataJoint = sendDataToJoint(queryProbeDataFilter);
				//对字符串进行拼接处理
				if (sendDataJoint != null) {
					// 1.代表发送过滤规则
					dataJson = sendDataJoint;
				} else {
					return R.failed("获取数据为空值！！！！！");
				}
				//根据id获取到探针服务器ip
				String pip = queryProbeDataFilter.getProbeServerIp();
				//设置超时时间
				DefaultSocketClient.proTimeOut = 60;
				SocketClient socketClient = new DefaultSocketClient("BIMP", "udprobe",
						300);
				Base64.Encoder encoder = Base64.getEncoder();
				String xmlbase64 = encoder.encodeToString(dataJson.getBytes("UTF-8"));
//				ProbeSocketResponse<?> psr = socketClient.execute(new ProbeSocketRequest(1, xmlbase64, null), pip);
				boolean publishConfig = nacosConfigManager.getConfigService().publishConfig(pip + "_filter.json", "UDPROBE_CONF", dataJson);
//				if (psr != null) {
//					if (psr.getResult() != null) {
						//判断探针返回的状态码，如果为301则同步成功
						if (publishConfig) {
							count++;
							//设置状态
							UpdateWrapper<ConfProbeDataFilter> updateWrapper = new UpdateWrapper<>();
							updateWrapper.eq("id", Integer.parseInt(idd));
							updateWrapper.set("filter_status",2);
							super.update(updateWrapper);
							resultlistip.remove(idd);
							successid.add(idd);
							log.info("探针服务器IP:" + pip + "--规则发送响应结果:成功！");
							//有任务在执行
						} else {
							log.info("探针服务器IP:" + pip + "规则发送响应结果:失败! " );
						}
//					}
//				}
			} catch (Exception e) {
				log.error("发送过滤规则超时---" + e);
				resultData.put("ids", resultlistip);
				return R.ok( resultData,"发送规则失败");
			}
		}
		if (count == 0) {
			resultData.put("ids", resultlistip);
			return R.ok(resultData, "发送规则失败");
		} else {
			resultData.put("count", count);
			resultData.put("total", proId.length);
			if (!CollectionUtil.isEmpty(runid)) {
				resultData.put("runid", runid);
			}
			resultData.put("ids", resultlistip);
			resultData.put("sucid", successid);
			return R.ok(  resultData, "发送规则成功！" + count + "/" + proId.length);
		}
	}

	/**
	 * 字符串拼接，组成探针服务器需要的json
	 */
	private String sendDataToJoint(ConfProbeDataFilter confProbeDataFilter) {
		StringBuilder sendString = new StringBuilder();
		try {
			//id
			sendString.append("[{\"id\":");
			sendString.append(confProbeDataFilter.getId());
			//开始时间
			sendString.append(",\"startTime\":\"");
			sendString.append(confProbeDataFilter.getStartTime());
			//执行时间
			sendString.append("\",\"timeCountdown\":");
			sendString.append(confProbeDataFilter.getTimeCountdown());
			//关键字集合
			sendString.append(",\"keywordSet\":\"");
			if(confProbeDataFilter.getKeyword()!=null) {
				sendString.append(confProbeDataFilter.getKeyword());
			}
			//IP关键字集合
			sendString.append("\",\"ipSaveSet\":\"");
			if(confProbeDataFilter.getIpSaveSet()!=null) {
				sendString.append(confProbeDataFilter.getIpSaveSet());
			}
			//屏蔽IP关键字集合
			sendString.append("\",\"ipDropSet\":\"");
			if(confProbeDataFilter.getIpDropSet()!=null) {
				sendString.append(confProbeDataFilter.getIpDropSet());
			}
			//是否是会话模式
			sendString.append("\",\"sessionModel\":");
			if (confProbeDataFilter.getSessionModel() != null && confProbeDataFilter.getSessionModel() == 0) {
				sendString.append("false");
			} else {
				sendString.append("true");
			}
			sendString.append("}]");
		} catch (Exception e) {
			throw new IllegalArgumentException("字符拼接出现错误！");
		}
		log.info(sendString.toString());
		return sendString.toString();
	}

	/**
	 * 停止抓包
	 *
	 * @param ids id集
	 * @return Result
	 */
	@Override
	public R stop(List<Integer> ids) {
		Map<String, Object> resultData = new HashMap<>(6);
		int count = 0;
		//返回失败的id
		List<Integer> resultlistip = ids;
		//返回成功的id
		List<Integer> resultsucid = new ArrayList<>();
		try {
			for (Integer idd : ids) {
				//根据id获取到探针服务器ip
				ConfProbeDataFilter queryProbeDataFilter = super.getById(idd);
				String propertySource = null;
				String ip = null;
				if (queryProbeDataFilter != null){
					ip = queryProbeDataFilter.getProbeServerIp();
					propertySource = nacosConfigManager.getConfigService().getConfig(ip + "_common_config.ini", "UDPROBE_CONF", 1000);
				}

				//如果获取不到相关配置文件, 也默认 获取探针失败
				if (propertySource != null) {
					ByteArrayInputStream inputStream = new ByteArrayInputStream(propertySource.getBytes());
					Ini wini = new Wini(inputStream);
					if (wini.containsKey("business_common")) {
						Ini.Section businessCommon = wini.get("business_common");
						businessCommon.put("device_is_active", "false");
						ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
						wini.store(outputStream);
						String iniString = outputStream.toString();
						nacosConfigManager.getConfigService().publishConfig(ip + "_common_config.ini", "UDPROBE_CONF", iniString);
						count++;
						log.info("探针IP：" + ip + "--停止抓包成功--");
						resultlistip.remove(idd);
						resultsucid.add(idd);
						//设置状态
						UpdateWrapper<ConfProbeDataFilter> updateWrapper = new UpdateWrapper<>();
						updateWrapper.eq("id", idd);
						updateWrapper.set("filter_status", 0);
						super.update(updateWrapper);
						log.info("清理" + ip + "成功...");
					}
				}
			}
		} catch (Exception e) {
			log.error("停止抓包失败,连接超时..." + e);
			resultData.put("ids", resultlistip);
			return R.ok(resultData, "停止抓包失败！");
		}
		if (count == 0) {
			resultData.put("ids", resultlistip);
			return R.ok(resultData, "停止抓包失败");
		} else {
			resultData.put("count", count);
			resultData.put("total", ids.size());
			resultData.put("ids", resultlistip);
			resultData.put("sucid", resultsucid);
			return R.ok(resultData, "停止抓包成功！" + count + "/" + ids.size());
		}
	}
}
